package Modelo;

import java.util.Stack;

public class Pooglin implements PoseedorDeHabilidad {
	private boolean vivo;
	private Numeros velocidad;
	private Numeros velocidadFatalChoque;
	private int sentido;
	private int tipoVelocidad;
	private Habilidad paso;
	private Habilidad caida;
	public int getSentidoVertical(){
		return tipoVelocidad;
	}
	public void caer(){
		tipoVelocidad=Constantes.abajo;
	}
	public void caminar(){
		tipoVelocidad=Constantes.reposo;
	}
	private Habilidad habilidad;
	private Stack <Habilidad> habilidadesAEjecutar;
	
	public Numeros getVelocidad(){
		return velocidad;
	}
	
	public void setVelocidad(Numeros velocidad){
		this.velocidad=velocidad;
	}
	
	public int getSentido(){
		return sentido;
	}
	public void invertirSentido(){
		if(sentido==Constantes.derecha)
			sentido=Constantes.izquierda;
		else
			sentido=Constantes.derecha;
	}
	private Mapa mapa;
	public Mapa getMapa(){
		return mapa;
	}
	
	private boolean detenido;	
	public boolean estaDetenido(){
		return detenido;
	}
	
	public void detener(){
		detenido=true;
	}
	
	public Pooglin(Mapa mapa){
		this.mapa=mapa;
		tipoVelocidad=Constantes.reposo;
		velocidadFatalChoque= new Real(Constantes.gravedad*Constantes.maxBloqueCaida);
		velocidad= new Real(0);	
		sentido=Constantes.direccionInicial;
		habilidad=null;
		habilidadesAEjecutar=new Stack<Habilidad>();
		vivo=true;
		detenido=false;
		paso= new Paso();
		caida= new Caida();
	}
	
	public void actuar(){
		// orden de ejecucion: caer - habilidad - caminar
		if(estaDetenido())
			return;
		ejecutarPila();
		int cantidad= velocidad.dividir(new Entero(Constantes.velocidad)).toEnt();
		while(cantidad>1&&tipoVelocidad==Constantes.reposo){
			ejecutarPila();			
			cantidad--;
			if(velocidad.compareTo(new Entero(Constantes.velocidad))==0)
				cantidad=1;
			if(tipoVelocidad==Constantes.reposo)
				break;
		}
//		System.out.println("velocidad= " + velocidad.toEnt());
		
	}
	
	private void ejecutarPila(){
		habilidadesAEjecutar.push(paso);
		if(habilidad!=null)
			habilidadesAEjecutar.push(habilidad);
		habilidadesAEjecutar.push(caida);
		// si puedo, ejecuto las habilidades de la pila
		while(!habilidadesAEjecutar.empty()&&estaVivo()){
			Habilidad aEjecutar=(Habilidad) habilidadesAEjecutar.pop();
			if(aEjecutar.esEjecutableSobre(this)){
			//	long tiempo=aEjecutar.tiempoDeEjecucion(this);
				aEjecutar.ejecutarSobre(this);
				
				// este if es medio cualquiera pero...
				if(!((aEjecutar instanceof Caida)&&(habilidad instanceof PlatilloVolador)))
					break; // el tiempo no se usa con esta nueva implementacion
						   // sin multithread, pero si se usara, seria el 
				       	   // resultado calculado en base a la velocidad.
			}
		}	
		habilidadesAEjecutar.removeAllElements();
	}
	
	public void morir() {
		vivo=false;
	}

	public void chocar() {
		if(velocidadFatalChoque.compareTo(velocidad)<=0&&tipoVelocidad==Constantes.abajo){
			mapa.getBloqueDondeEsta(this).desalojar(this);
			morir();		
		}
		caminar();
		velocidad= new Entero(0);
	}

	public boolean estaVivo() {
		return vivo;
	}

	public boolean asignarHabilidad(Habilidad habilidad){
		if(this.habilidad==null){
			this.habilidad=habilidad;
			
		//	System.out.println("ahora tengo " + habilidad);
			
			return true;
		}
		return false;
	}
	
	public void eliminarHabilidad(Habilidad habilidad){
		this.habilidad=null;
	}
	@Override
	public boolean ejecutoHabilidad() {
		if(habilidad==null)
			return false;
		return habilidad.seEjecuto();
	}
	@Override
	public Habilidad getHabilidad() {
		return habilidad;
	}
}